-
Notifications
You must be signed in to change notification settings - Fork 168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix race to unregister sync session #5886
Fix race to unregister sync session #5886
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great catch!
It can be difficult to write a test to hit races like this, but could you add a test anyways even if it doesn't reproduce 100% of the time?
It is indeed pretty hard to hit all conditions to create a good test for this, but I'll give it a try. |
I don't think this fixes the race condition. As soon as
This requires much more unfavorable scheduling than before, but the race condition is still present. |
Good catch. I think one way to solve the problem once and for all is to only access |
…ss m_sync_manager only under a lock.
Recursive mutexes are an extremely bad idea that should almost never be used. |
I agree, but I don't see any other obvious solution. My last commit shows how it would work. On a side note, we have a project to refactor/rework this part of the codebase, but it would be nice find a fix until then. |
I think the simplest fix is probably for everywhere that's capturing a reference to the sync manager and then unlocking to instead store a shared_ptr and then unlock. |
…ne. Access m_sync_manager only under a lock." This reverts commit a8ba34b.
Thanks for the suggestion. I'm personally not a big fan of this approach (and we use it in a few other places), but it's good enough for the time being. We'll hopefully get rid of some of these once we refactor the code. I added a unit test to cover the original issue. |
What, How & Why?
There is a race when a sync session is closed at the same time with being detached from the SyncManager (as result of the app being destroyed).
This can lead to a sync session being unregistered from the SyncManager after the SyncManager was deallocated (use-after-free).
To prevent this happening, we extend the lifetime of the SyncManager (if the SyncManager is still alive) until the session is unregistered.
Fixes #5752, realm/realm-dart#858.
☑️ ToDos
C-API, if public C++ API changed.